-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Legacy/overview auth! #430
Conversation
📝 Walkthrough📝 WalkthroughWalkthroughThe pull request includes several modifications primarily focused on the Changes
Possibly related PRs
Suggested labels
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
...rrespondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewHandler.cs
Fixed
Show fixed
Hide fixed
...rrespondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewHandler.cs
Fixed
Show fixed
Hide fixed
...rrespondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewHandler.cs
Fixed
Show fixed
Hide fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🧹 Outside diff range and nitpick comments (15)
src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewResponse.cs (2)
8-12
: Add XML documentation for public properties.Since these properties are part of a public API, they should be documented with XML comments to improve maintainability and provide better IntelliSense support.
+ /// <summary> + /// Gets or sets a value indicating whether the correspondence can be deleted. + /// </summary> public bool AllowDelete { get; set; } + /// <summary> + /// Gets or sets a value indicating whether the user is authorized to write. + /// </summary> public bool AuthorizedForWrite { get; set; } + /// <summary> + /// Gets or sets a value indicating whether the user is authorized to sign. + /// </summary> public bool AuthorizedForSign { get; set; } + /// <summary> + /// Gets or sets the date and time when the correspondence was archived. + /// </summary> public DateTimeOffset? Archived { get; set; } + /// <summary> + /// Gets or sets the minimum authentication level required. + /// </summary> public int MinimumAuthenticationlevel { get; set; }
12-12
: Consider adding validation for MinimumAuthenticationlevel.The
MinimumAuthenticationlevel
property should have validation to ensure it contains a valid authentication level value. Consider using an enum or adding range validation.- public int MinimumAuthenticationlevel { get; set; } + private int _minimumAuthenticationLevel; + public int MinimumAuthenticationlevel + { + get => _minimumAuthenticationLevel; + set + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "Authentication level cannot be negative."); + } + _minimumAuthenticationLevel = value; + } + }Alternatively, consider using an enum:
public enum AuthenticationLevel { None = 0, Level1 = 1, Level2 = 2, Level3 = 3, Level4 = 4 } public AuthenticationLevel MinimumAuthenticationlevel { get; set; }src/Altinn.Correspondence.Core/Repositories/IAltinnAuthorizationService.cs (2)
8-8
: Add XML documentation for the new method.Please add XML documentation to describe the method's purpose, parameters, return value, and possible exceptions. This will help maintain consistency with C# best practices and improve code maintainability.
+ /// <summary> + /// Checks user access and retrieves the minimum authentication level required for the specified resource. + /// </summary> + /// <param name="resourceId">The ID of the resource to check access for.</param> + /// <param name="rights">List of access levels to check against.</param> + /// <param name="cancellationToken">Optional cancellation token.</param> + /// <param name="recipientOrgNo">Optional recipient organization number.</param> + /// <returns>The minimum authentication level if access is granted, null otherwise.</returns> Task<int?> CheckUserAccessAndGetMinimumAuthLevel(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default, string? recipientOrgNo = null);
8-8
: Consider splitting the method responsibilities.The method currently combines two distinct responsibilities: checking access and retrieving the authentication level. While this might be more efficient in terms of API calls, it could make the interface less flexible and harder to maintain.
Consider these alternatives:
- Keep the current implementation if the two operations are always needed together and performance is critical.
- Split into separate methods if they might need to be used independently:
Task<bool> CheckUserAccess(...); Task<int?> GetMinimumAuthLevel(...);The current implementation is acceptable if you confirm that:
- These operations are always performed together
- The combined operation provides significant performance benefits
- The implementation doesn't complicate the authorization service's logic
src/Altinn.Correspondence.API/Models/LegacyCorrespondenceOverviewExt.cs (1)
7-11
: Enhance class documentation for authentication context.While the documentation is present, it could be more descriptive about the class's role in authentication and its relationship with the A2 component.
Consider expanding the documentation:
/// <summary> -/// An object representing an overview of a correspondence for the legacy API +/// An object representing an overview of a correspondence for the legacy API, extending the base overview +/// with additional authentication-related properties required for the A2 component integration. +/// This class supports the enhanced authentication process through PDP requests. /// </summary>src/Altinn.Correspondence.API/Mappers/LegacyCorrespondenceOverviewMapper.cs (2)
37-37
: Fix property name casing.The property name "MinimumAuthenticationlevel" should be "MinimumAuthenticationLevel" to follow C# naming conventions.
- MinimumAuthenticationlevel = correspondenceOverview.MinimumAuthenticationlevel, + MinimumAuthenticationLevel = correspondenceOverview.MinimumAuthenticationLevel,
11-39
: Consider using AutoMapper for complex mappings.The current manual mapping approach could become hard to maintain as the model grows. Consider using AutoMapper to reduce boilerplate code and potential mapping errors.
Example implementation:
private static IMapper _mapper; static LegacyCorrespondenceOverviewMapper() { var config = new MapperConfiguration(cfg => { cfg.CreateMap<LegacyGetCorrespondenceOverviewResponse, LegacyCorrespondenceOverviewExt>() .ForMember(dest => dest.Content, opt => opt.MapFrom(src => CorrespondenceContentMapper.MapToExternal(src.Content))) .ForMember(dest => dest.ReplyOptions, opt => opt.MapFrom(src => CorrespondenceReplyOptionsMapper.MapListToExternal(src.ReplyOptions))) // ... other complex mappings }); _mapper = config.CreateMapper(); } internal static LegacyCorrespondenceOverviewExt MapToExternal(LegacyGetCorrespondenceOverviewResponse correspondenceOverview) { return _mapper.Map<LegacyCorrespondenceOverviewExt>(correspondenceOverview); }src/Altinn.Correspondence.Application/DependencyInjection.cs (1)
Line range hint
1-72
: Consider improving section organization.To enhance maintainability and clarity, consider:
- Using region directives or comments to clearly separate sections
- Keeping related handlers together
- Following a consistent registration pattern within each section
Example structure:
public static void AddApplicationHandlers(this IServiceCollection services) { // Core Handlers #region Attachment Handlers services.AddScoped<InitializeAttachmentHandler>(); // ... other attachment handlers #endregion #region Correspondence Handlers services.AddScoped<InitializeCorrespondencesHandler>(); // ... other correspondence handlers #endregion #region Legacy Handlers services.AddScoped<LegacyGetCorrespondencesHandler>(); services.AddScoped<LegacyGetCorrespondenceOverviewHandler>(); services.AddScoped<LegacyGetCorrespondenceHistoryHandler>(); #endregion // ... other sections }src/Altinn.Correspondence.API/Controllers/LegacyCorrespondenceController.cs (2)
Line range hint
73-73
: Resolve return type uncertainty in GetCorrespondenceHistoryThere's a TODO comment questioning whether the return type should be
LegacyCorrespondenceHistoryExt
. This should be resolved before merging.Would you like me to help analyze the appropriate return type based on the codebase usage patterns?
Line range hint
1-24
: Add automated tests as mentioned in PR objectivesThe PR objectives mention that automated tests haven't been added. Consider adding tests for:
- Authentication/PDP request flow
- Legacy mapper implementations
- Error handling scenarios
Would you like assistance in generating the test implementations?
src/Altinn.Correspondence.Application/Errors.cs (1)
57-57
: Consider enhancing the error message for better troubleshooting.The implementation follows the established pattern and uses appropriate error code sequencing and HTTP status. However, the error message could be more descriptive to aid in troubleshooting.
Consider this enhancement:
- public static Error InvalidPartyId = new Error(49, "Invalid partyId", HttpStatusCode.BadRequest); + public static Error InvalidPartyId = new Error(49, "The provided partyId is invalid or does not exist", HttpStatusCode.BadRequest);src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs (4)
48-55
: Refactor theCheckUserAccess
method to improve readability and maintainability.Consider extracting the validation logic into a separate method to make the code more readable and maintainable. This will also help in reusing the validation logic in other methods.
public async Task<bool> CheckUserAccess(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default, string? recipientOrgNo = null) { var user = _httpContextAccessor.HttpContext?.User; var validationResult = await ValidateCheckUserAccess(user, resourceId, cancellationToken); if (validationResult.HasValue) { return validationResult.Value; } var responseContent = await CheckUserAccess(user, rights, resourceId, recipientOrgNo, cancellationToken); if (responseContent is null) { return false; } return ValidateAuthorizationResponse(responseContent, user); } private async Task<bool?> ValidateCheckUserAccess(ClaimsPrincipal? user, string resourceId, CancellationToken cancellationToken) { if (_httpClient.BaseAddress is null) { _logger.LogWarning("Authorization service disabled"); return true; } var serviceOwnerId = await _resourceRepository.GetServiceOwnerOfResource(resourceId, cancellationToken); if (string.IsNullOrWhiteSpace(serviceOwnerId)) { _logger.LogWarning("Service owner not found for resource"); return false; } if (user is null) { _logger.LogError("Unexpected null value. User was null when checking access to resource"); return false; } return null; }
58-73
: Consider adding XML documentation comments for the newCheckUserAccessAndGetMinimumAuthLevel
method.Adding XML documentation comments will help other developers understand the purpose, parameters, and return value of this method.
/// <summary> /// Checks if the user has access to the specified resource and returns the minimum authentication level. /// </summary> /// <param name="resourceId">The ID of the resource to check access for.</param> /// <param name="rights">The list of resource access levels to check.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <param name="recipientOrgNo">The recipient organization number (optional).</param> /// <returns>The minimum authentication level if the user has access, otherwise null.</returns> public async Task<int?> CheckUserAccessAndGetMinimumAuthLevel(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default, string? recipientOrgNo = null) { // ... }
75-88
: Consider adding logging for theCheckMigrationAccess
method.Adding logging statements will help in monitoring and debugging the migration access checks.
public async Task<bool> CheckMigrationAccess(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default) { if (_hostEnvironment.IsDevelopment()) { _logger.LogInformation("Migration access granted in development environment."); return true; } var serviceOwnerId = await _resourceRepository.GetServiceOwnerOfResource(resourceId, cancellationToken); if (string.IsNullOrWhiteSpace(serviceOwnerId)) { _logger.LogWarning("Service owner not found for resource. Migration access denied."); return false; } _logger.LogInformation("Migration access granted for resource with service owner."); return true; }
110-125
: Consider renaming theCheckUserAccess
method to avoid confusion with the publicCheckUserAccess
method.Since this method is a private helper method, renaming it to something like
GetUserAccessResponse
orFetchUserAccessResponse
would help differentiate it from the public method and clarify its purpose.private async Task<XacmlJsonResponse?> GetUserAccessResponse(ClaimsPrincipal user, List<ResourceAccessLevel> rights, string resourceId, string? recipientOrgNo, CancellationToken cancellationToken) { // ... }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (11)
src/Altinn.Correspondence.API/Controllers/LegacyCorrespondenceController.cs
(2 hunks)src/Altinn.Correspondence.API/Mappers/LegacyCorrespondenceOverviewMapper.cs
(1 hunks)src/Altinn.Correspondence.API/Models/LegacyCorrespondenceOverviewExt.cs
(1 hunks)src/Altinn.Correspondence.Application/DependencyInjection.cs
(1 hunks)src/Altinn.Correspondence.Application/Errors.cs
(1 hunks)src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewHandler.cs
(4 hunks)src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewResponse.cs
(1 hunks)src/Altinn.Correspondence.Core/Repositories/IAltinnAuthorizationService.cs
(1 hunks)src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationDevService.cs
(1 hunks)src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs
(2 hunks)src/Altinn.Correspondence.Integrations/Idporten/IdPortenXacmlMapper.cs
(1 hunks)
🧰 Additional context used
📓 Learnings (1)
src/Altinn.Correspondence.Application/DependencyInjection.cs (1)
Learnt from: CelineTrammi
PR: Altinn/altinn-correspondence#413
File: src/Altinn.Correspondence.Application/DependencyInjection.cs:0-0
Timestamp: 2024-10-29T13:40:14.651Z
Learning: In Altinn.Correspondence.Application, handlers with similar names—such as UploadAttachmentHandler, GetAttachmentDetailsHandler, GetAttachmentOverviewHandler, and PurgeAttachmentHandler—may have multiple distinct implementations and are intentionally registered separately in DependencyInjection.cs.
🪛 GitHub Check: CodeQL
src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewHandler.cs
[failure] 35-35: User-controlled bypass of sensitive method
This condition guards a sensitive action, but a user-provided value controls it.
This condition guards a sensitive action, but a user-provided value controls it.
[failure] 35-35: User-controlled bypass of sensitive method
This condition guards a sensitive action, but a user-provided value controls it.
[failure] 35-35: User-controlled bypass of sensitive method
This condition guards a sensitive action, but a user-provided value controls it.
🔇 Additional comments (19)
src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewResponse.cs (1)
6-7
: LGTM! Class declaration follows proper conventions.
The class name and inheritance structure align well with the legacy correspondence overview enhancement objective.
src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationDevService.cs (1)
18-21
:
Add documentation and development-only warnings for the mock implementation.
The hardcoded authentication level of 3 in this development service could be dangerous if accidentally used in production. Consider:
- Adding XML documentation to explain this is a development-only implementation
- Adding a warning log when this mock method is called
- Documenting why level 3 was chosen as the mock value
Here's a suggested improvement:
+ /// <summary>
+ /// Development-only implementation that returns a mock authentication level.
+ /// WARNING: This should never be used in production as it bypasses real authorization checks.
+ /// </summary>
+ /// <returns>Always returns authentication level 3 for development purposes.</returns>
public Task<int?> CheckUserAccessAndGetMinimumAuthLevel(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default, string? recipientOrgNo = null)
{
+ // TODO: Add warning log that this development implementation is being used
return Task.FromResult((int?)3);
}
Let's verify if there are any production configurations that might accidentally use this development service:
✅ Verification successful
Development service is properly controlled by configuration
The mock implementation is safe as it's only used in development scenarios. The service registration in DependencyInjection.cs
shows that AltinnAuthorizationDevService
is only registered when maskinportenSettings.ClientId
is empty or null, which is the case in:
- Development environment (empty ClientId in appsettings.Development.json)
- Test scenarios (CustomWebApplicationFactory)
In production, when MaskinportenSettings.ClientId is configured, the real AltinnAuthorizationService
is registered instead.
While the original review's documentation suggestions are still valuable for clarity, this is not a critical issue as the development service cannot be accidentally used in production.
Suggested improvements remain valid but optional:
+ /// <summary>
+ /// Development-only implementation that returns a mock authentication level.
+ /// This implementation is only used when MaskinportenSettings.ClientId is not configured.
+ /// </summary>
public Task<int?> CheckUserAccessAndGetMinimumAuthLevel(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default, string? recipientOrgNo = null)
{
return Task.FromResult((int?)3);
}
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for service registration of AltinnAuthorizationDevService
rg -l "AltinnAuthorizationDevService" | grep -i "startup\|program\|configuration"
Length of output: 81
Script:
#!/bin/bash
# Let's try a broader search to understand where this service is used and registered
rg -l "AltinnAuthorizationDevService"
Length of output: 264
Script:
#!/bin/bash
# Search for any Program.cs or Startup.cs files that might contain service registration
fd "Program.cs|Startup.cs"
Length of output: 69
Script:
#!/bin/bash
# Search for any configuration or DI setup related to authorization services
rg -i "services\.add.*authorization" -A 3 -B 3
Length of output: 5932
Script:
#!/bin/bash
# Check if there are any environment-specific configurations
fd -e json "appsettings"
Length of output: 130
Script:
#!/bin/bash
# Let's check the DependencyInjection.cs to understand how the dev service is configured
cat src/Altinn.Correspondence.Integrations/DependencyInjection.cs
Length of output: 4240
Script:
#!/bin/bash
# Let's also check the appsettings.Development.json to see if there's any configuration that controls this
cat src/Altinn.Correspondence.API/appsettings.Development.json
Length of output: 1417
src/Altinn.Correspondence.API/Models/LegacyCorrespondenceOverviewExt.cs (1)
1-6
: LGTM! Clean namespace organization.
The using directives and namespace declaration follow proper conventions.
src/Altinn.Correspondence.API/Mappers/LegacyCorrespondenceOverviewMapper.cs (3)
1-5
: LGTM! Clean imports following architecture boundaries.
The imports are minimal, focused, and properly organized according to clean architecture principles.
7-8
: LGTM! Appropriate class design.
The class is correctly designed as an internal static mapper, following the single responsibility principle.
37-38
: Validate authentication-related properties.
Given that this PR focuses on authentication enhancements, these properties should be validated to ensure security requirements are met.
src/Altinn.Correspondence.API/Controllers/LegacyCorrespondenceController.cs (3)
Line range hint 95-107
: LGTM: GetCorrespondences implementation
The method correctly uses the legacy mapper and maintains proper error handling.
64-64
: Verify LegacyCorrespondenceOverviewMapper implementation
The mapper has been renamed from CorrespondenceOverviewMapper
to LegacyCorrespondenceOverviewMapper
. Let's ensure the new mapper is properly implemented with all required properties mentioned in the AI summary (AllowDelete, AuthorizedForSign, MinimumAuthenticationlevel).
#!/bin/bash
# Check if the new mapper exists and contains required properties
ast-grep --pattern 'class LegacyCorrespondenceOverviewMapper {
$$$
MapToExternal($_) {
$$$
}
}'
Line range hint 1-24
: Missing PDP request implementation mentioned in PR objectives
The PR objectives mention adding a PDP request for authentication, but the implementation is not visible in the controller. Ensure that the PDP request is properly implemented for secure authentication handling.
Let's check if PDP implementation exists elsewhere:
src/Altinn.Correspondence.Application/Errors.cs (1)
57-57
: Verify error usage in authentication flow.
Since this error is part of the authentication enhancement, let's verify its integration.
✅ Verification successful
Error is properly integrated in authentication flow
The InvalidPartyId
error is correctly used in the LegacyGetCorrespondenceOverviewHandler
where it validates the party ID before proceeding with the correspondence overview request. The validation checks for invalid values (0 or int.MinValue) and returns the error appropriately.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for InvalidPartyId usage to ensure it's properly integrated
echo "Searching for InvalidPartyId usage..."
rg -l "InvalidPartyId" --type cs
# Search for related party validation logic
echo -e "\nSearching for party validation logic..."
rg "partyId.*invalid" --type cs -i
Length of output: 553
Script:
#!/bin/bash
# Let's check the usage context in LegacyGetCorrespondenceOverviewHandler.cs
echo "Checking InvalidPartyId usage context in handler:"
rg "InvalidPartyId" -B 5 -A 5 src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewHandler.cs
# Let's also check if there are any party validation methods
echo -e "\nChecking for party validation methods:"
ast-grep --pattern 'private $_ $_($$$) {
$$$
partyId
$$$
}'
Length of output: 952
src/Altinn.Correspondence.Integrations/Idporten/IdPortenXacmlMapper.cs (2)
131-160
:
Add security validations and audit logging.
For security-critical code:
- Add null checks for input parameters
- Add audit logging for authorization decisions
- Consider making the class internal unless public access is required
Apply these security improvements:
+using Microsoft.Extensions.Logging;
public static int? GetMinimumAuthLevel(XacmlJsonResponse response, ClaimsPrincipal user)
{
+ if (response == null)
+ throw new ArgumentNullException(nameof(response));
+ if (user == null)
+ throw new ArgumentNullException(nameof(user));
+
int? minimumAuthLevel = null;
foreach (var result in response.Response)
{
if (!result.Decision.Equals(XacmlContextDecision.Permit.ToString()))
{
+ _logger.LogInformation("Authorization denied for user {UserId}", user.Identity?.Name);
return null;
}
Let's check for existing security measures:
#!/bin/bash
# Check for existing audit logging
rg -B 5 "LogInformation|LogWarning|LogError" --type cs
# Check for other security validations
ast-grep --pattern 'throw new ArgumentNullException($name)'
131-160
: Document relationship with ValidateIdportenAuthorizationResponse.
The new method extracts minimum auth level while ValidateIdportenAuthorizationResponse
validates it. Consider:
- Adding XML documentation to clarify the relationship
- Potentially refactoring to share common obligation extraction logic
- Adding unit tests to verify consistent behavior
Let's verify the usage pattern:
src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewHandler.cs (6)
12-12
: LGTM!
The class name change from GetCorrespondenceOverviewHandler
to LegacyGetCorrespondenceOverviewHandler
is appropriate given the focus on legacy correspondence overview in this update.
33-33
: LGTM!
The change in the return type of the Process
method from OneOf<GetCorrespondenceOverviewResponse, Error>
to OneOf<LegacyGetCorrespondenceOverviewResponse, Error>
aligns with the introduction of the new LegacyGetCorrespondenceOverviewResponse
class, providing a more specific response type for the legacy correspondence overview.
37-37
: LGTM!
The introduction of the Errors.InvalidPartyId
error return case provides a more specific and informative error message when the PartyId
is invalid, improving error handling and clarity.
43-43
: LGTM!
The error return case Errors.CouldNotFindOrgNo
is appropriate when the userParty
is null or both the SSN
and OrgNumber
are empty, indicating that the organizational number could not be found for the given party.
50-54
: LGTM!
The addition of the CheckUserAccessAndGetMinimumAuthLevel
method call to the IAltinnAuthorizationService
interface enhances the user access check by retrieving the minimum authentication level required for accessing the correspondence. If the required level is not met, the method now returns Errors.LegacyNoAccessToCorrespondence
, providing a more specific error for unauthorized access scenarios.
Line range hint 104-131
: LGTM!
The construction of the LegacyGetCorrespondenceOverviewResponse
object has been updated to include additional properties such as MinimumAuthenticationlevel
, AuthorizedForSign
, DueDateTime
, AllowDelete
, Archived
, and PropertyList
. These changes enhance the detail and specificity of the response provided by the handler, aligning with the requirements of the legacy correspondence overview.
src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs (1)
Line range hint 89-108
: LGTM!
The ValidateCheckUserAccess
method encapsulates the validation logic nicely and improves the readability of the CheckUserAccess
method.
...respondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewResponse.cs
Outdated
Show resolved
Hide resolved
src/Altinn.Correspondence.API/Models/LegacyCorrespondenceOverviewExt.cs
Outdated
Show resolved
Hide resolved
src/Altinn.Correspondence.API/Models/LegacyCorrespondenceOverviewExt.cs
Outdated
Show resolved
Hide resolved
src/Altinn.Correspondence.API/Mappers/LegacyCorrespondenceOverviewMapper.cs
Show resolved
Hide resolved
src/Altinn.Correspondence.API/Mappers/LegacyCorrespondenceOverviewMapper.cs
Show resolved
Hide resolved
src/Altinn.Correspondence.API/Mappers/LegacyCorrespondenceOverviewMapper.cs
Show resolved
Hide resolved
src/Altinn.Correspondence.Integrations/Idporten/IdPortenXacmlMapper.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (6)
src/Altinn.Correspondence.Application/GetCorespondences/LegacyGetCorrespondencesHandler.cs (3)
Line range hint
141-146
: Implementation required: Add resource access and authorization checksThe TODO comments indicate missing critical functionality:
- Resource access verification for parties
- Multi-request authorization using PDP
- Authentication level population
These are core requirements mentioned in the PR objectives but are not implemented yet.
Would you like assistance in implementing:
- Resource access verification using the Resource Registry API?
- Multi-request authorization using the Authorization API?
- Integration tests for the new authorization flow?
Line range hint
39-45
: Improve error handling for party validationThe current error handling uses generic messages and needs improvement:
Errors.CouldNotFindOrgNo
is used for multiple different scenarios- TODO comments indicate incomplete error handling
Consider implementing specific error types:
- return Errors.CouldNotFindOrgNo; // TODO: Update to better error message + return Errors.InvalidPartyId(request.OnbehalfOfPartyId, "OnbehalfOfPartyId cannot be 0 or minimum value"); - return Errors.CouldNotFindOrgNo; // TODO: Update to better error message + return Errors.PartyNotFound(request.OnbehalfOfPartyId, "Party must have either SSN or OrgNumber");
Based on the shell script results, I can now provide a final response:
Authentication and Authorization Implementation Required
The review comment is accurate. The code shows several authentication-related issues:
Authentication level is hardcoded to 0 in multiple places:
LegacyGetCorrespondencesHandler.cs
:MinimumAuthenticationLevel = 0, // Insert from response from PDP multirequest
LegacyGetCorrespondenceHistoryHandler.cs
:AuthenticationLevel = 0, // TODO: Get authentication level
The codebase has proper authentication infrastructure in place:
- JWT Bearer authentication is configured
- OpenID Connect is implemented
- PDP (Policy Decision Point) integration exists
- Authentication level validation logic exists in
IdPortenXacmlMapper.cs
andDialogTokenXacmlMapper.cs
The TODO comments accurately identify the missing implementation:
// TODO: Authorize each correspondence using multirequests // https://docs.altinn.studio/authorization/guides/xacml/#request-for-multiple-decisions // https://docs.altinn.studio/api/authorization/spec/#/Decision/post_authorize
The authentication level should be obtained from PDP responses instead of being hardcoded, and proper authorization checks need to be implemented using the existing infrastructure.
🔗 Analysis chain
Line range hint
1-146
: PR Objectives Alignment CheckThis implementation doesn't fully meet the PR objectives:
- The PDP request for authentication is not implemented
- Authentication level is hardcoded
- Error handling needs improvement
- Tests are missing as noted in PR description
Consider implementing these requirements before merging this PR to ensure proper authentication and authorization.
Let's verify test coverage:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for test files related to this handler fd -e cs -e cs "Test|Spec" | rg -i "LegacyGetCorrespondences"Length of output: 61
Script:
#!/bin/bash # Let's first check if there are any test files in the repository fd -e cs "Test" -t f # Then let's check for any PDP/authentication related code rg -i "pdp|authentication" -A 5 -B 5 src/ # Let's also check for any TODO comments related to authentication rg "TODO.*auth" src/Length of output: 76359
src/Altinn.Correspondence.Integrations/Idporten/IdPortenXacmlMapper.cs (2)
131-157
: Add XML documentation for better maintainability.Since this method is public and plays a crucial role in authentication, consider adding XML documentation to describe its purpose, parameters, return value, and behavior.
+/// <summary> +/// Extracts the minimum authentication level from the XACML response. +/// </summary> +/// <param name="response">The XACML response containing authorization decisions and obligations.</param> +/// <param name="user">The claims principal representing the authenticated user.</param> +/// <returns>The minimum required authentication level if found; null if unauthorized or no level specified.</returns> public static int? GetMinimumAuthLevel(XacmlJsonResponse response, ClaimsPrincipal user)
144-144
: Extract the obligation category as a constant.Consider extracting the magic string "urn:altinn:minimum-authenticationlevel" as a private constant at the class level for better maintainability and reusability.
+private const string MinimumAuthLevelCategory = "urn:altinn:minimum-authenticationlevel"; -XacmlJsonAttributeAssignment? obligation = GetObligation("urn:altinn:minimum-authenticationlevel", obligations); +XacmlJsonAttributeAssignment? obligation = GetObligation(MinimumAuthLevelCategory, obligations);src/Altinn.Correspondence.API/Mappers/LegacyCorrespondenceOverviewMapper.cs (1)
11-11
: Use camelCase for local variable namesAccording to C# naming conventions, local variables should be in camelCase. Please rename
Correspondence
tocorrespondence
.Apply this diff to correct the variable name:
- var Correspondence = new LegacyCorrespondenceOverviewExt + var correspondence = new LegacyCorrespondenceOverviewExt
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (9)
src/Altinn.Correspondence.API/Mappers/LegacyCorrespondenceOverviewMapper.cs
(1 hunks)src/Altinn.Correspondence.API/Models/LegacyCorrespondenceItemExt.cs
(1 hunks)src/Altinn.Correspondence.API/Models/LegacyCorrespondenceOverviewExt.cs
(1 hunks)src/Altinn.Correspondence.Application/DependencyInjection.cs
(1 hunks)src/Altinn.Correspondence.Application/GetCorespondences/LegacyGetCorrespondencesHandler.cs
(1 hunks)src/Altinn.Correspondence.Application/GetCorespondences/LegacyGetCorrespondencesResponse.cs
(1 hunks)src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewHandler.cs
(4 hunks)src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewResponse.cs
(1 hunks)src/Altinn.Correspondence.Integrations/Idporten/IdPortenXacmlMapper.cs
(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- src/Altinn.Correspondence.API/Models/LegacyCorrespondenceItemExt.cs
- src/Altinn.Correspondence.Application/GetCorespondences/LegacyGetCorrespondencesResponse.cs
🚧 Files skipped from review as they are similar to previous changes (4)
- src/Altinn.Correspondence.API/Models/LegacyCorrespondenceOverviewExt.cs
- src/Altinn.Correspondence.Application/DependencyInjection.cs
- src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewHandler.cs
- src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewResponse.cs
🧰 Additional context used
📓 Learnings (1)
src/Altinn.Correspondence.Application/GetCorespondences/LegacyGetCorrespondencesHandler.cs (1)
Learnt from: CelineTrammi
PR: Altinn/altinn-correspondence#413
File: src/Altinn.Correspondence.Application/GetCorrespondenceHistory/LegacyGetCorrespondenceHistoryResponse.cs:17-21
Timestamp: 2024-10-29T13:10:17.164Z
Learning: The `PartyId` and `AuthenticationLevel` properties in the `LegacyUser` class (in `src/Altinn.Correspondence.Application/GetCorrespondenceHistory/LegacyGetCorrespondenceHistoryResponse.cs`) are still under development, and the correct validation has not been determined yet.
🔇 Additional comments (2)
src/Altinn.Correspondence.Integrations/Idporten/IdPortenXacmlMapper.cs (1)
131-157
: Implementation looks good!
The implementation is robust and secure:
- Properly handles invalid decisions by returning null
- Safely parses integer values using TryParse
- Efficiently tracks minimum value
- Gracefully handles missing or invalid obligations
src/Altinn.Correspondence.API/Mappers/LegacyCorrespondenceOverviewMapper.cs (1)
1-42
: Code implementation is correct and follows best practices
The mapping function accurately maps all properties from the input object to the output object. The code is well-structured and maintains clarity.
src/Altinn.Correspondence.Application/GetCorespondences/LegacyGetCorrespondencesHandler.cs
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice to have some auth!
src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs
Outdated
Show resolved
Hide resolved
…inn-correspondence into legacy/overview-auth!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (1)
src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs (1)
110-125
: Enhance error logging in AuthorizeRequest method.While the error handling is good, consider adding more detailed logging for troubleshooting:
- Log the HTTP status code when the response is not successful
- Log the request details (excluding sensitive data) when authorization fails
Apply this diff to enhance logging:
var response = await _httpClient.PostAsJsonAsync("authorization/api/v1/authorize", jsonRequest, cancellationToken); if (!response.IsSuccessStatusCode) { + _logger.LogError("Authorization request failed with status code: {StatusCode}", response.StatusCode); return null; } var responseContent = await response.Content.ReadFromJsonAsync<XacmlJsonResponse>(cancellationToken: cancellationToken); if (responseContent is null) { - _logger.LogError("Unexpected null or invalid json response from Authorization."); + _logger.LogError("Unexpected null or invalid json response from Authorization for resource: {ResourceId}", resourceId); return null; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs
(2 hunks)
🔇 Additional comments (2)
src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs (2)
58-73
:
Review hardcoded authentication level.
The method returns a hardcoded authentication level of 3 when validation passes. This might not be appropriate for all cases and could potentially bypass security requirements.
Let's verify if there are any configuration settings or constants defining the authentication levels:
Consider making the authentication level configurable or deriving it from the resource requirements instead of hardcoding it.
75-88
:
Review security implications and method naming.
The method has several concerns:
- It bypasses all security checks in development environment
- The method name suggests migration access checks, but it only verifies service owner existence
- No actual migration-specific access rules are being checked
Consider:
- Adding a configuration flag instead of relying on environment for security bypasses
- Implementing actual migration-specific access rules
- Renaming the method to better reflect its purpose, e.g.,
ValidateServiceOwnerAccess
Let's check for any migration-related configurations or rules:
✅ Verification successful
Let me analyze the search results. I can see that there is a comprehensive migration system in place:
- There's a dedicated
MigrationController
with proper authorization using thealtinn:correspondence.migrate
scope - The
CheckMigrationAccess
method is part of a larger migration system that includes:- Migration repositories
- Migration status tracking
- Migration handlers for both correspondence and attachments
- Proper authorization checks
Let me verify the actual implementation of authorization checks in development:
Based on the search results, I can now provide a comprehensive response about the security implications of the CheckMigrationAccess
method:
Development bypass is consistent with application-wide security patterns
The development environment bypasses in the codebase follow a consistent pattern used for:
- Skipping malware scans in development (
UploadHelper.cs
) - JWT lifetime validation (
DependencyInjection.cs
) - Migration access checks (
AltinnAuthorizationService.cs
)
This is a standard practice in the codebase for development convenience, and other security-critical features follow the same pattern. The method's implementation is appropriate because:
- The bypass only affects development environments
- It's part of a proper migration system with dedicated authorization scopes (
altinn:correspondence.migrate
) - The service owner validation provides a basic security check in production
The method name accurately reflects its purpose as it's part of a comprehensive migration system that includes:
- Migration controllers and handlers
- Migration status tracking
- Proper authorization checks
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for migration-related code
rg -i "migration|migrate" --type cs
Length of output: 53166
Script:
#!/bin/bash
# Search for development environment checks in authorization services
rg -A 5 "IsDevelopment\(\)" --type cs
Length of output: 7157
src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs
Show resolved
Hide resolved
* Initial functionality for legacy correspondenceOverview * improvements * better naming * better text for api route * add auth for legacy overview * better error message * fix variable names * improve minAuthLevel function * Better naming --------- Co-authored-by: Hammerbeck <[email protected]>
* Add logic for downloading attachment for A2 GUI * null check fileName * Checkout before using action (#423) * Fix deploy permission (#425) * Fix: Ensure correspondence is fetched before updating to Read or Confirmed (#427) * fix: validate correspondence has been fetched before it can be read and confirmed * update tests * typo fix * Handle potential null value for IsConfirmationNeeded * reuse factory for client initialization * rename testname * add Fetched to statuses available for Recipient * Legacy/overview auth! (#430) * Initial functionality for legacy correspondenceOverview * improvements * better naming * better text for api route * add auth for legacy overview * better error message * fix variable names * improve minAuthLevel function * Better naming --------- Co-authored-by: Hammerbeck <[email protected]> * Missing reference to Github environment in CI/CD (#436) * Add logic to check if user is recipient * Fix deploy permission (#425) * Fix: Ensure correspondence is fetched before updating to Read or Confirmed (#427) * fix: validate correspondence has been fetched before it can be read and confirmed * update tests * typo fix * Handle potential null value for IsConfirmationNeeded * reuse factory for client initialization * rename testname * add Fetched to statuses available for Recipient * Missing reference to Github environment in CI/CD (#436) * remove duplicate and rewrite userClaim logic * remove unused usings * add norwegian org prefix to recipient check --------- Co-authored-by: Roar Mjelde <[email protected]> Co-authored-by: Andreas Hammerbeck <[email protected]> Co-authored-by: Hammerbeck <[email protected]>
Description
Adds pdp request for correct auth for legacy correspondence overview
Introduces some new attributes to the response object needed by A2
Related Issue(s)
Verification
Documentation
Summary by CodeRabbit
New Features
LegacyCorrespondenceOverviewMapper
for enhanced data mapping.LegacyCorrespondenceOverviewExt
class with additional properties for correspondence details.CheckUserAccessAndGetMinimumAuthLevel
method.LegacyGetCorrespondenceOverviewResponse
with new properties.CheckMigrationAccess
method for improved access validation.Bug Fixes
MinimumAuthenticationLevel
for consistency.Documentation
Chores